package com.settlement.system.parse.formula;

import org.apache.commons.lang3.StringUtils;

/**
 * 订单稽核等式验证
 *
 * @author Ximi
 * @since 2020/10/09
 */
public class OrderAuditValidate implements Validate {

    public String[] splits = new String[]{"<>", ">=", "<=", ">", "<"};

    public String[] mathOperation = new String[]{"+", "-", "*", "/"};

    @Override
    public boolean validate(String formula) {

        if (StringUtils.isEmpty(formula)) {
            return false;
        }

        for (int index = 0; index < splits.length; index++) {

            String[] childFormulas = formula.split(splits[index]);
            if (childFormulas.length > 2) {
                return false;
            }

            if (childFormulas.length == 2) {
                return checkMathFormulas(childFormulas[0]) & checkMathFormulas(childFormulas[1]);
            }
        }
        return false;
    }

    /**
     * @param mathFormulas
     * @return
     */
    private Boolean checkMathFormulas(String mathFormulas) {

        for (int index = 0; index < splits.length; index++) {
            if (mathFormulas.contains(splits[index])) {
                return false;
            }
        }

        Integer rightBracketNumber = 0;
        StringBuilder childMathFormula = new StringBuilder();
        for (int index = 0; index < mathFormulas.length(); index++) {

            //左括号
            if ("(".equals(mathFormulas.charAt(index))) {
                //左括号还包含左括号,把当前括号当做前面左括号的表达式
                if (rightBracketNumber != 0) {
                    childMathFormula.append(mathFormulas.charAt(index));
                    //是第一个左口号,并且前面有未解析的字符,解析异常
                } else if (rightBracketNumber == 0 && childMathFormula.length() != 0) {
                    return false;
                }

                rightBracketNumber++;

                continue;

            }
            //右括号
            if (")".equals(mathFormulas.charAt(index))) {
                //一个左括号匹配一个右口号,减少一个右括号
                rightBracketNumber--;

                //右括号的数量大于左括号,解析异常
                if (rightBracketNumber < 0) {
                    return false;
                }

                //括号号的数量少于左括号,属于前面口号的表达式
                if (rightBracketNumber > 0) {
                    childMathFormula.append(mathFormulas.charAt(index));
                }

                //左右括号相等,解析子表达式
                if (rightBracketNumber == 0) {
                    if (checkMathFormulas(childMathFormula.toString())) {
                        childMathFormula.setLength(0);
                    } else {
                        return false;
                    }
                }

                continue;
            }

            //没有括号,并且是操作符
            boolean flag = ("+".equals(mathFormulas.charAt(index))
                    || "-".equals(mathFormulas.charAt(index))
                    || "*".equals(mathFormulas.charAt(index))
                    || "/".equals(mathFormulas.charAt(index)))
                    && rightBracketNumber == 0;
            if (flag) {

                //解析占位符
                if (OrderPlaceHoldEunm.getByName(childMathFormula.toString()) == null) {
                    return false;
                }

                //最后一个字符,并且还是站位符
                if (index == mathFormulas.length() - 1) {
                    return false;
                }

                childMathFormula.setLength(0);

                continue;
            }

            childMathFormula.append(mathFormulas.charAt(index));
        }

        if (childMathFormula.length() != 0 && OrderPlaceHoldEunm.getByName(childMathFormula.toString()) == null) {
            return false;
        }

        return true;
    }


}
